package zcatt.demo;

import static java.lang.System.out;

import java.lang.annotation.Annotation;
import java.lang.reflect.*;

public class Main {

	public static void main(String[] args) {
		
		//#. attributes
		Person person = new Manager();
		Class<?> personClass = person.getClass();
		Class<Person> person2Class = (Class<Person>)person.getClass();
		out.println("personClass getSimpleName() =" + personClass.getSimpleName());
		out.println("person2Class getSimpleName() =" + person2Class.getSimpleName());		//仍是Manager

		Manager manager = new Manager();
		manager.setJobYears(10);
		Class<Manager> managerClass = (Class<Manager>) manager.getClass();
		out.println("managerClass getSimpleName() =" + managerClass.getSimpleName());
		out.println("managerClass getName() =" + managerClass.getName());
		out.println("managerClass getCanonicalName() =" + managerClass.getCanonicalName());
		out.println("managerClass getPackageName() =" + managerClass.getPackageName());
		Module module = managerClass.getModule();
		out.println("managerClass getModule() =" + module);
		
		Class<?> superClass = managerClass.getSuperclass();
		out.println("managerClass superClass() =" + superClass.getName());
		
		out.println("isInterface()="+managerClass.isInterface());
		out.println("isLocalClass()="+managerClass.isLocalClass());
		
		out.println("classLoader hierachy: ---------");
		ClassLoader curClassLoader = managerClass.getClassLoader();
		ClassLoader preClassLoader = null;
		while(curClassLoader != null)
		{
			out.println("classLoader = " + curClassLoader);
			Package[] packages = curClassLoader.getDefinedPackages();
			out.println("packages = ");
			for(Package e : packages)
				out.println(e);
			curClassLoader = curClassLoader.getParent();
		}
		
		//#. create obj and call its method
		try {
			Class<?> clazz = Class.forName("zcatt.demo.Manager");
			Object inst = clazz.getDeclaredConstructor().newInstance();
			out.println("isInstance() = " + managerClass.isInstance(inst));
			out.println("Class compare = " + (managerClass == inst.getClass()));
			
			Method getJobYearsMethod = clazz.getMethod("getJobYears", null);
			getJobYearsMethod.invoke(manager);		//10 years
			
		} catch(Exception e)
		{
			e.printStackTrace();
		}
		
		//#.reflect
		try {
			Class<?> clazz = Class.forName("zcatt.demo.Person");
			
			out.println("personClass annotations:   ------------");
			Annotation[] anns = clazz.getDeclaredAnnotations();
			for(Annotation e : anns)
			{
				out.println(e);
			}

			out.println("personClass fields:   ------------");
			Field[] fields = clazz.getDeclaredFields();
			for(Field e : fields)
			{
				out.println(e);
			}
			
			out.println("personClass methods:   ------------");
			Method[] methods = clazz.getDeclaredMethods();
			for(Method e : methods)
			{
				out.println(e);
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
		
	}

}
